﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AusProject.OrderDataControls;
using AusProject.OrderComponents;
using System.IO;

namespace AusProject
{
    public partial class FormOrderSummaryDesigner : Form
    {
        public FormOrderSummaryDesigner()
        {
            InitializeComponent();

            SetFormSize(1260, 1782);
            SetMainTitleHeight(200);

            selectedControl = null;
            ShowProperties();
        }


        #region OrderForm DragDrop Ability

        DataBox newCreatedControl = null;

        private void panelOrderForm_DragEnter(object sender, DragEventArgs e)
        {
            newCreatedControl = (TextDataBox)e.Data.GetData(typeof(TextDataBox));
            if (newCreatedControl == null)
            {
                newCreatedControl = (NumberDataBox)e.Data.GetData(typeof(NumberDataBox));
            }
            if (newCreatedControl == null)
            {
                newCreatedControl = (DateDataBox)e.Data.GetData(typeof(DateDataBox));
            }
            if (newCreatedControl == null)
            {
                newCreatedControl = (DropListDataBox)e.Data.GetData(typeof(DropListDataBox));
            }
            if (newCreatedControl == null)
            {
                newCreatedControl = (CheckDataBox)e.Data.GetData(typeof(CheckDataBox));
            }
            if (newCreatedControl == null)
            {
                newCreatedControl = (TickDataBox)e.Data.GetData(typeof(TickDataBox));
            }

            if (newCreatedControl != null)
            {
                e.Effect = DragDropEffects.Copy;
                panelMainTitle.Controls.Add(newCreatedControl);
                newCreatedControl.Location = panelMainTitle.PointToClient(new Point(e.X, e.Y));
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }

        private void panelOrderForm_DragOver(object sender, DragEventArgs e)
        {
            if (newCreatedControl != null)
            {
                newCreatedControl.Location = panelMainTitle.PointToClient(new Point(e.X, e.Y));
            }
        }

        private void panelOrderForm_DragLeave(object sender, EventArgs e)
        {
            if (newCreatedControl != null)
            {
                panelMainTitle.Controls.Remove(newCreatedControl);
                newCreatedControl.Location = new Point(0, 0);
                newCreatedControl = null;
            }
        }

        private void panelOrderForm_DragDrop(object sender, DragEventArgs e)
        {
            InitNewControl(newCreatedControl);
        }

        #endregion


        #region Add New Control

        private void AddNewControl(DataBox databox)
        {
            panelMainTitle.Controls.Add(databox);
            InitNewControl(databox);
        }

        private void InitNewControl(DataBox databox)
        {
            databox.Enter += new System.EventHandler(this.control_Enter);
            databox.Move += new System.EventHandler(this.control_Move);
            databox.Resize += new System.EventHandler(this.control_Resize);
            databox.TitleChanged += new System.EventHandler(this.control_TitleChanged);
            databox.Focus();
        }


        private void btnTextDataBox_Click(object sender, EventArgs e)
        {
            AddNewControl(new TextDataBox());
        }

        private void btnTextDataBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                btnTextDataBox.DoDragDrop(new TextDataBox(), DragDropEffects.Copy);
            }
        }


        private void btnNumberDataBox_Click(object sender, EventArgs e)
        {
            AddNewControl(new NumberDataBox());
        }

        private void btnNumberDataBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                btnNumberDataBox.DoDragDrop(new NumberDataBox(), DragDropEffects.Copy);
            }
        }


        private void btnDateDataBox_Click(object sender, EventArgs e)
        {
            AddNewControl(new DateDataBox());
        }

        private void btnDateDataBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                btnDateDataBox.DoDragDrop(new DateDataBox(), DragDropEffects.Copy);
            }
        }


        private void btnDropListDataBox_Click(object sender, EventArgs e)
        {
            AddNewControl(new DropListDataBox());
        }

        private void btnDropListDataBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                btnDropListDataBox.DoDragDrop(new DropListDataBox(), DragDropEffects.Copy);
            }
        }

        private void btnCheckDataBox_Click(object sender, EventArgs e)
        {
            AddNewControl(new CheckDataBox());
        }

        private void btnCheckDataBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                btnCheckDataBox.DoDragDrop(new CheckDataBox(), DragDropEffects.Copy);
            }
        }

        private void btnTickDataBox_Click(object sender, EventArgs e)
        {
            AddNewControl(new TickDataBox());
        }

        private void btnTickDataBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                btnTickDataBox.DoDragDrop(new TickDataBox(), DragDropEffects.Copy);
            }
        }

        #endregion


        DataBox selectedControl = null;

        private void ShowProperties()
        {
            if (selectedControl != null)
            {
                #region Show properties of selected control

                lblControlType.Text = selectedControl.ToString();

                txtTitle.Text = selectedControl.Title;
                txtTitle.Enabled = true;

                txtDefaultValue.Text = selectedControl.DefaultValue;
                txtDefaultValue.Enabled = true;

                if (selectedControl.Editable)
                {
                    cmbEditable.SelectedIndex = 0;
                }
                else
                {
                    cmbEditable.SelectedIndex = 1;
                }
                cmbEditable.Enabled = true;

                switch (selectedControl.BorderMode)
                {
                    case DataControlBorderMode.None:
                        cmbBorderMode.SelectedIndex = 0;
                        break;
                    case DataControlBorderMode.Full:
                        cmbBorderMode.SelectedIndex = 1;
                        break;
                    case DataControlBorderMode.TitleOnly:
                        cmbBorderMode.SelectedIndex = 2;
                        break;
                    case DataControlBorderMode.ValueOnly:
                        cmbBorderMode.SelectedIndex = 3;
                        break;
                }
                cmbBorderMode.Enabled = true;

                txtFont.Enabled = true;
                txtFont.Text = selectedControl.Font.Name + "; " + selectedControl.Font.Size
                    + (selectedControl.Font.Bold ? "; Bold" : "") + (selectedControl.Font.Italic ? "; Italic" : "");
                btnSelectFont.Enabled = true;

                txtLeft.Text = selectedControl.Left.ToString();
                txtLeft.Enabled = true;
                txtTop.Text = selectedControl.Top.ToString();
                txtTop.Enabled = true;
                txtWidth.Text = selectedControl.Width.ToString();
                txtWidth.Enabled = true;
                txtHeight.Text = selectedControl.Height.ToString();
                txtHeight.Enabled = true;

                #endregion

                btnEditValueList.Enabled = (selectedControl is DropListDataBox) || (selectedControl is TickDataBox);

                btnDeleteControl.Enabled = true;
            }
            else
            {
                #region Clear and disable property controls

                lblControlType.Text = "None";

                txtTitle.Text = "";
                txtTitle.Enabled = false;

                txtDefaultValue.Text = "";
                txtDefaultValue.Enabled = false;

                cmbEditable.SelectedIndex = 0;
                cmbEditable.Enabled = false;

                cmbBorderMode.SelectedIndex = 0;
                cmbBorderMode.Enabled = false;

                txtFont.Text = "";
                txtFont.Enabled = false;
                btnSelectFont.Enabled = false;

                txtLeft.Text = "";
                txtLeft.Enabled = false;
                txtTop.Text = "";
                txtTop.Enabled = false;
                txtWidth.Text = "";
                txtWidth.Enabled = false;
                txtHeight.Text = "";
                txtHeight.Enabled = false;

                #endregion

                btnEditValueList.Enabled = false;

                btnDeleteControl.Enabled = false;
            }
        }


        #region Data control event Handlers

        private void control_Enter(object sender, EventArgs e)
        {
            selectedControl = (DataBox)sender;
            ShowProperties();
        }

        private void control_Resize(object sender, EventArgs e)
        {
            selectedControl = (DataBox)sender;

            //TODO: use form width/height instead of panelOrderForm.Width/Height

            if (selectedControl.Left + selectedControl.Width < 3)
            {
                selectedControl.Left = 3 - selectedControl.Width;
            }
            if (selectedControl.Left > panelMainTitle.Width - 3)
            {
                selectedControl.Left = panelMainTitle.Width - 3;
            }
            if (selectedControl.Top + selectedControl.Height < 3)
            {
                selectedControl.Top = 3 - selectedControl.Height;
            }
            if (selectedControl.Top > panelMainTitle.Height - 3)
            {
                selectedControl.Top = panelMainTitle.Height - 3;
            }
            ShowProperties();
        }

        private void control_Move(object sender, EventArgs e)
        {
            selectedControl = (DataBox)sender;
            if (selectedControl.Left + selectedControl.Width < 3)
            {
                selectedControl.Left = 3 - selectedControl.Width;
            }
            if (selectedControl.Left > panelMainTitle.Width - 3)
            {
                selectedControl.Left = panelMainTitle.Width - 3;
            }
            if (selectedControl.Top + selectedControl.Height < 3)
            {
                selectedControl.Top = 3 - selectedControl.Height;
            }
            if (selectedControl.Top > panelMainTitle.Height - 3)
            {
                selectedControl.Top = panelMainTitle.Height - 3;
            }
            ShowProperties();
        }

        private void control_TitleChanged(object sender, EventArgs e)
        {
            selectedControl = (DataBox)sender;
            ShowProperties();
        }

        #endregion Data control event Handlers


        private void txtTitle_Leave(object sender, EventArgs e)
        {
            if (selectedControl != null)
            {
                selectedControl.Title = txtTitle.Text;
                txtTitle.Text = selectedControl.Title;
            }
        }

        private void cmbEditable_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (selectedControl != null)
            {
                selectedControl.Editable = (cmbEditable.SelectedIndex == 0);
            }
        }

        private void cmbBorderMode_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (selectedControl != null)
            {
                switch (cmbBorderMode.SelectedIndex)
                {
                    case 0:
                        selectedControl.BorderMode = DataControlBorderMode.None;
                        break;
                    case 1:
                        selectedControl.BorderMode = DataControlBorderMode.Full;
                        break;
                    case 2:
                        selectedControl.BorderMode = DataControlBorderMode.TitleOnly;
                        break;
                    case 3:
                        selectedControl.BorderMode = DataControlBorderMode.ValueOnly;
                        break;
                }
            }
        }

        private void txtDefaultValue_Leave(object sender, EventArgs e)
        {
            if (selectedControl != null)
            {
                selectedControl.DefaultValue = txtDefaultValue.Text;
                txtDefaultValue.Text = selectedControl.DefaultValue;
            }
        }

        private void txtLeft_Leave(object sender, EventArgs e)
        {
            if (selectedControl != null)
            {
                int v;
                if (int.TryParse(txtLeft.Text, out v))
                {
                    if ((v + selectedControl.Width > 3) && (v < splitWhole.Panel1.Width - 3))
                    {
                        selectedControl.Left = v;
                    }
                }
                txtLeft.Text = selectedControl.Left.ToString();
            }
        }

        private void txtTop_Leave(object sender, EventArgs e)
        {
            if (selectedControl != null)
            {
                int v;
                if (int.TryParse(txtTop.Text, out v))
                {
                    if ((v + selectedControl.Height > 3) && (v < splitWhole.Panel1.Height - 3))
                    {
                        selectedControl.Top = v;
                    }
                }
                txtTop.Text = selectedControl.Top.ToString();
            }
        }

        private void txtWidth_Leave(object sender, EventArgs e)
        {
            if (selectedControl != null)
            {
                int v;
                if (int.TryParse(txtWidth.Text, out v))
                {
                    selectedControl.Width = v;
                }
                txtWidth.Text = selectedControl.Width.ToString();
            }
        }

        private void txtHeight_Leave(object sender, EventArgs e)
        {
            if (selectedControl != null)
            {
                int v;
                if (int.TryParse(txtHeight.Text, out v))
                {
                    selectedControl.Height = v;
                }
                txtHeight.Text = selectedControl.Height.ToString();
            }
        }

        private void txtTitle_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == 13)
            {
                txtTitle_Leave(null, null);
            }
        }

        private void txtLeft_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == 13)
            {
                txtLeft_Leave(null, null);
            }
        }

        private void txtTop_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == 13)
            {
                txtTop_Leave(null, null);
            }
        }

        private void txtWidth_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == 13)
            {
                txtWidth_Leave(null, null);
            }
        }

        private void txtHeight_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == 13)
            {
                txtHeight_Leave(null, null);
            }
        }

        private void btnDeleteControl_Click(object sender, EventArgs e)
        {
            if (selectedControl != null)
            {
                panelMainTitle.Controls.Remove(selectedControl);
                selectedControl = null;
                ShowProperties();
            }
        }

        private void panelOrderForm_MouseClick(object sender, MouseEventArgs e)
        {
            panelMainTitle.Focus();
            selectedControl = null;
            ShowProperties();
        }

        private void txtTitle_Enter(object sender, EventArgs e)
        {
            txtTitle.SelectAll();
        }

        private void txtDefaultValue_Enter(object sender, EventArgs e)
        {
            txtDefaultValue.SelectAll();
        }

        private void txtLeft_Enter(object sender, EventArgs e)
        {
            txtLeft.SelectAll();
        }

        private void txtTop_Enter(object sender, EventArgs e)
        {
            txtTop.SelectAll();
        }

        private void txtWidth_Enter(object sender, EventArgs e)
        {
            txtWidth.SelectAll();
        }

        private void txtHeight_Enter(object sender, EventArgs e)
        {
            txtHeight.SelectAll();
        }

        private void cmbEditable_MouseClick(object sender, MouseEventArgs e)
        {
            cmbEditable.DroppedDown = true;
        }

        private void cmbBorderMode_MouseClick(object sender, MouseEventArgs e)
        {
            cmbBorderMode.DroppedDown = true;
        }

        private void btnEditValueList_Click(object sender, EventArgs e)
        {
            if (selectedControl is DropListDataBox)
            {
                FormDropListValues frmValueListEditor = new FormDropListValues();
                frmValueListEditor.ListValue = ((DropListDataBox)selectedControl).ListValue;
                frmValueListEditor.ShowDialog();
                if (frmValueListEditor.HasAccepted)
                {
                    ((DropListDataBox)selectedControl).ListValue = frmValueListEditor.ListValue;
                }
            }
            else  // must be TickBoxControl
            {
                FormTickBoxOptions frmTickBoxOptions = new FormTickBoxOptions();
                frmTickBoxOptions.Option1Label = ((TickDataBox)selectedControl).Option1Label;
                frmTickBoxOptions.Option2Label = ((TickDataBox)selectedControl).Option2Label;
                frmTickBoxOptions.ShowDialog();
                if (frmTickBoxOptions.HasAccepted)
                {
                    ((TickDataBox)selectedControl).Option1Label = frmTickBoxOptions.Option1Label;
                    ((TickDataBox)selectedControl).Option2Label = frmTickBoxOptions.Option2Label;
                }
            }
        }


        private void addNewsectionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FormComponentTypeChooser chooser = new FormComponentTypeChooser();
            chooser.ShowDialog();
            if (chooser.Accepted)
            {
                OrderComponent oc = new OrderComponent();
                oc.ImportInfo(chooser.SelectedComponentInfo);

                oc.Width = formWidth;
                oc.ContextMenuStrip = new System.Windows.Forms.ContextMenuStrip();
                oc.MouseClick += new MouseEventHandler(OrderComponent_Clicked);

                oc.RowClicked += new EventHandler<RowClickedEventArgs>(Row_Clicked);
                flowOrderData.Controls.Add(oc);
            }
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (selectedOC != null)
            {
                flowOrderData.Controls.Remove(selectedOC);
                selectedOC = null;
            }
        }

        OrderComponent selectedOC = null;

        private void OrderComponent_Clicked(object sender, MouseEventArgs e)
        {
            selectedOC = (OrderComponent)sender;
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                cmnuSection.Show(((Control)sender).PointToScreen(e.Location));
            }
        }

        private void Row_Clicked(object sender, RowClickedEventArgs e)
        {
            OrderComponent_Clicked(sender, e);
        }

        private void flowOrderData_MouseClick(object sender, MouseEventArgs e)
        {
            flowOrderData.Focus();
            selectedControl = null;
            ShowProperties();
        }


        public void ImportFormInfo(OrderSummaryFormInfo formInfo)
        {
            txtFormTitle.Text = formInfo.Title;
            SetFormSize(formInfo.Width, formInfo.Height);

            panelMainTitle.Controls.Clear();
            foreach (DataBoxInfo dboxInfo in formInfo.MainTitleDataBoxes)
            {
                AddNewControl(dboxInfo.CreateDataBox());
            }

            flowOrderData.Controls.Clear();
            foreach (OrderComponentInfo ocInfo in formInfo.OrderComponents)
            {
                OrderComponent oc = new OrderComponent();
                oc.ImportInfo(ocInfo);

                oc.ContextMenuStrip = new System.Windows.Forms.ContextMenuStrip();
                oc.MouseClick += new MouseEventHandler(OrderComponent_Clicked);

                oc.RowClicked += new EventHandler<RowClickedEventArgs>(Row_Clicked);
                flowOrderData.Controls.Add(oc);
            }

            this.Invalidate();
        }

        public OrderSummaryFormInfo ExportFormInfo()
        {
            List<DataBoxInfo> mainTitleDataBoxes = new List<DataBoxInfo>();
            foreach (DataBox dbox in panelMainTitle.Controls)
            {
                mainTitleDataBoxes.Add(dbox.ExportDataBoxInfo());
            }

            List<OrderComponentInfo> orderComponents = new List<OrderComponentInfo>();
            foreach (OrderComponent oc in flowOrderData.Controls)
            {
                orderComponents.Add(oc.ExportInfo());
            }

            return new OrderSummaryFormInfo(txtFormTitle.Text, formWidth, formHeight, mainTitleDataBoxes, orderComponents, mainTitleHeight);
        }


        private void btnTestOrderForm_Click(object sender, EventArgs e)
        {
            FormOrderSummaryRuntime runForm = new FormOrderSummaryRuntime();
            runForm.LoadForm(ExportFormInfo(), false);
            this.Hide();
            runForm.ShowDialog();
            this.Show();
        }


        private bool accepted = false;

        public bool Accepted
        {
            get { return accepted; }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            accepted = true;
            this.Close();
        }

        private void btnDiscard_Click(object sender, EventArgs e)
        {
            accepted = false;
            this.Close();
        }

        private int formWidth;
        private int formHeight;
        private int mainTitleHeight;

        private void cmbFormSize_SelectedIndexChanged(object sender, EventArgs e)
        {
            switch (cmbFormSize.SelectedIndex)
            {
                case 0: // A4
                    SetFormSize(1260, 1782);
                    break;
            }
        }

        public void SetFormSize(int width, int height)
        {
            formWidth = width;
            formHeight = height;

            int idx = -1;
            if ((formWidth == 1260) && (formHeight == 1782))
            {
                idx = 0;
            }

            if (idx != cmbFormSize.SelectedIndex)   // avoid recurrence from cmbFormSize_SelectedIndexChanged
            {
                cmbFormSize.SelectedIndex = idx;
            }

            panelMainTitle.Width = formWidth;

            flowOrderData.MinimumSize = new Size(formWidth, 350);
            foreach (OrderComponent oc in flowOrderData.Controls)
            {
                oc.Width = formWidth;
            }
        }


        private void txtMainTitleHeight_Leave(object sender, EventArgs e)
        {
            txtMainTitleHeight.Text = txtMainTitleHeight.Text.Trim();

            int height;
            if (int.TryParse(txtMainTitleHeight.Text, out height))
            {
                SetMainTitleHeight(height);
            }
            else
            {
                txtMainTitleHeight.Text = mainTitleHeight.ToString();
            }
        }

        public void SetMainTitleHeight(int height)
        {
            mainTitleHeight = height;
            panelMainTitle.Height = height;

            if (height.ToString().CompareTo(txtMainTitleHeight.Text) != 0)
            {
                txtMainTitleHeight.Text = height.ToString();
            }
        }

        private void txtMainTitleHeight_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == 13)
            {
                txtMainTitleHeight_Leave(null, null);
            }
        }

        private void txtMainTitleHeight_Enter(object sender, EventArgs e)
        {
            txtMainTitleHeight.SelectAll();
        }


        public void SetTitle(string formTitle, int formID)
        {
            string oFormTitle = string.IsNullOrEmpty(formTitle) ? "" : " - " + formTitle;
            string oFormID = formID >= 0 ? " (#" + formID + ")" : " (NoID)";
            this.Text = "Order Summary Form Designer" + oFormTitle + oFormID;
        }

        private void btnSelectFont_Click(object sender, EventArgs e)
        {
            fontDialogDataBox.Font = selectedControl.Font;
            try
            {
                if (fontDialogDataBox.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    selectedControl.Font = fontDialogDataBox.Font;
                }
            }
            catch
            {
                MessageBox.Show("The font you have selected is invalid!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                ShowProperties();
            }
        }
    }
}